Shader "post/dof"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Dof ("Dof", 2D) = "black" {}
    }

    SubShader{
        CGINCLUDE

        #include "UnityCG.cginc"

        sampler2D _CameraDepthTexture;
        sampler2D _MainTex;
        half4 _MainTex_TexelSize;
        sampler2D _Dof;
        float4 _BlurDir;
        float _Focus;
        float _NearScale;
        float _FarScale;


        struct v2fVert { 
			float4 pos : SV_POSITION;
            half2 uv :TEXCOORD0;
			half4 uvNear[3]: TEXCOORD1;
		};
		  
		v2fVert vertBlur(appdata_img v) {
			v2fVert o;
			o.pos = UnityObjectToClipPos(v.vertex);
			
			o.uv = v.texcoord;

            _BlurDir.xy *= _MainTex_TexelSize.xy;

            o.uvNear[0] = v.texcoord.xyxy + _BlurDir.xyxy * float4(1,1,-1,-1);
            o.uvNear[1] = v.texcoord.xyxy + _BlurDir.xyxy * float4(1,1,-1,-1) * 2.0;
            o.uvNear[2] = v.texcoord.xyxy + _BlurDir.xyxy * float4(1,1,-1,-1) * 3.0;
					 
			return o;
		}
		
		fixed4 fragBlur(v2fVert i) : SV_Target {
			float weight[4] = {0.4, 0.15, 0.1, 0.05};
			
			fixed3 sum = tex2D(_MainTex, i.uv).rgb * weight[0];
			
			for (int it = 0; it < 3; it++) {
				sum += tex2D(_MainTex, i.uvNear[it].xy).rgb * weight[it+1];
				sum += tex2D(_MainTex, i.uvNear[it].zw).rgb * weight[it+1];
			}
			
			return fixed4(sum, 1.0);
		}


        struct v2fDof {
            float4 pos : SV_POSITION;
            half4 uv : TEXCOORD0;
        };

        v2fDof vertDof(appdata_img v){
            v2fDof o;
            o.pos = UnityObjectToClipPos(v.vertex);
            o.uv.xy = v.texcoord;
            o.uv.zw = v.texcoord;

            #if UNITY_UV_STARTS_AT_TOP
            if (_MainTex_TexelSize.y < 0.0)
                o.uv.w =  1.0 - o.uv.w;
            #endif

            return o;
        }

        fixed4 fragDof(v2fDof i) : SV_Target{

            fixed4 blurCol = tex2D(_Dof, i.uv.zw);

            fixed4 originCol = tex2D(_MainTex, i.uv.xy);

            float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);

            depth = Linear01Depth(depth);

            fixed4 finalCol = depth > _Focus ? (lerp(blurCol, originCol, 1.0f-clamp((depth - _Focus) * _NearScale,0,1)  )) : blurCol;

            finalCol = depth < _Focus ? (lerp(blurCol, originCol, 1.0f-clamp((_Focus - depth) * _FarScale,0,1)  )) : blurCol;

            return finalCol;
        }

        ENDCG

        ZTest Always Cull Off ZWrite Off

        Pass{
            
			CGPROGRAM  
			#pragma vertex vertBlur 
			#pragma fragment fragBlur  
			
			ENDCG  
        }


        Pass {
            CGPROGRAM
            #pragma vertex vertDof
            #pragma fragment fragDof

            ENDCG
        }

    }
    FallBack Off
}
